package com.why.simpleboot.core.server.netty.handler;

import com.why.simpleboot.core.common.utils.SimpleIocUtils;
import com.why.simpleboot.core.common.utils.SimpleReflectUtils;
import com.why.simpleboot.core.core.ApplicationContext;
import com.why.simpleboot.core.core.entity.CreateMethodDefinitionFactory;
import com.why.simpleboot.core.core.entity.MethodDefinition;
import io.netty.handler.codec.http.FullHttpRequest;
import io.netty.handler.codec.http.FullHttpResponse;
import io.netty.handler.codec.http.HttpMethod;
import io.netty.handler.codec.http.QueryStringDecoder;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * @program: why-simpleboot-framework
 * @description:
 * @author: @why
 * @create: 2021-05-23 20:44
 **/
public abstract class AbstractRequestHandler implements RequestHandler {
    protected QueryStringDecoder requestParamDecoder;
    public RequestHandler nextRequestHandler;
    private Logger log = LoggerFactory.getLogger(AbstractRequestHandler.class);

    /**
     * 将请求参数和路径封装成一个对象
     * @param httpRequest
     * @return
     */
    protected MethodDefinition getMethodDefinition(FullHttpRequest httpRequest) {
        requestParamDecoder = new QueryStringDecoder(httpRequest.uri());
        log.info("uri is:{}", httpRequest.uri());
        String url = requestParamDecoder.path();
        log.info("url is :{}", url);
//注意一定要传递url，而不是uri
        MethodDefinition methodDefinition = CreateMethodDefinitionFactory.getMethodDefinition(httpRequest.method(), url);
        return methodDefinition;

    }

    /**
     * get和post都要使用该操作
     *
     * @param methodDefinition
     * @param args
     * @return
     */
    protected Object invokeMethodForTarget(MethodDefinition methodDefinition, Object[] args) {
        String beanName = SimpleIocUtils.getBeanName(methodDefinition.getMethod().getDeclaringClass());
//        获取bean对象
        Object target = ApplicationContext.getAnnotationApplicationContext().getBean(beanName);
        return SimpleReflectUtils.invokeMethod(target, methodDefinition.getMethod(), args);

    }

    /**
     * 判断能否处理当前请求 能处理 那就返回当前对象 不能处理那就返回下一个handler
     *
     * @param httpRequest
     * @param expectMethod
     * @return
     */
    protected RequestHandler canProcessCurrentRequest(FullHttpRequest httpRequest, HttpMethod expectMethod) {
        if (httpRequest.method() == expectMethod) {
            return this;
        } else {
            if (nextRequestHandler != null) {
                return this.nextRequestHandler;
            } else {
                return null;
            }
        }
    }


    @Override
    public abstract FullHttpResponse handle(FullHttpRequest httpRequest);

    @Override
    public void setNextRequestHandler(RequestHandler handler) {
        nextRequestHandler = handler;
    }


}
